package com.alias.app_interface;

import com.alias.model.Country;
import com.alias.model.Currency;
import com.alias.model.Employees;
import com.alias.DAOFactory.DAOFactory;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;

public class AdditionForm extends JFrame implements ActionListener {

    private static AdditionForm instance;

    private JFrame additionForm;
    private JPanel employee, topPanel, topPanelInvisible,
            personalInfo, position, address, photo;
    private JButton saveButton, closeButton, left, leftToBorder,
            right, rightToBorder;
    private JTextField code, name, surname, birthday, positionText, salary, city;
    private JTextArea location;
    private JTextPane age;
    private JComboBox gender, salaryCurrency, country;
    private JLabel codeLabel, nameLabel, surnameLabel, genderLabel, birthdayLabel,
            ageLabel, positionLabel, salaryLabel, countryLabel, cityLabel,
            locationLabel;
    private Employees employeeObj;
    private List<Employees> employeesList;
    private int employeeIndex;
    private JDialog aboutInfo;
    private JLabel aboutLabel;

    public static final Object[] genderConstatns = {"Male", "Female"};
    public static final Object[] countries = {"Belarus", "Russia", "USA", "Germany", "France"};


    private AdditionForm(String msg) {
        final String STATE = msg;
        //data initialization
        employeesList = EmployeesTable.getInstance().getEmployeesList();
        employeeIndex = 0;
        //form initialization
        additionForm = new JFrame("Addition form");
        additionForm.setSize(900, 700);
        additionForm.setPreferredSize(new Dimension(900, 700));
        additionForm.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                additionForm.setVisible(false);
                EmployeesTable.getInstance().getEmployeesTableForm().setVisible(true);
                instance = null;
            }
        });
        //dialog message initialization
        aboutInfo = new JDialog();
        aboutInfo.setTitle("Info");
        aboutInfo.setSize(270, 100);
        aboutInfo.setPreferredSize(new Dimension(270, 100));
        aboutLabel = new JLabel();
        aboutInfo.add(aboutLabel, BorderLayout.CENTER);
        //top panel and buttons
        topPanel = new JPanel();
        topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.LINE_AXIS));
        topPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        left = new JButton("<");
        left.addActionListener(this);
        leftToBorder = new JButton("<<");
        leftToBorder.addActionListener(this);
        right = new JButton(">");
        right.addActionListener(this);
        rightToBorder = new JButton(">>");
        rightToBorder.addActionListener(this);
        saveButton = new JButton("Save");
        saveButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (checker()) {
                    if (STATE.equals("add")) {
                        EmployeesTable.getInstance().addEmployee(employeeAdd());
                        additionForm.setVisible(false);
                        EmployeesTable.getInstance().getEmployeesTableForm().setVisible(true);
                        instance = null;
                    } else {
                        employeeEdit();
                    }
                }
            }
        });
        closeButton = new JButton("Close");
        closeButton.addActionListener(this);
        topPanel.add(left);
        topPanel.add(Box.createRigidArea(new Dimension(6, 0)));
        topPanel.add(leftToBorder);
        topPanel.add(Box.createRigidArea(new Dimension(6, 0)));
        topPanel.add(rightToBorder);
        topPanel.add(Box.createRigidArea(new Dimension(6, 0)));
        topPanel.add(right);
        topPanel.add(Box.createHorizontalGlue());
        topPanel.add(closeButton);
        topPanel.add(Box.createRigidArea(new Dimension(6, 0)));
        topPanel.add(saveButton);
        additionForm.add(topPanel, BorderLayout.PAGE_START);
        //Employees panel
        topPanelInvisible = new JPanel(new BorderLayout());
        topPanelInvisible.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        employee = new JPanel(new GridBagLayout());
        employee.setName("Employee");
        employee.setVisible(true);
        employee.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.BLACK), "Employee"));
        topPanelInvisible.add(employee, BorderLayout.CENTER);
        additionForm.add(topPanelInvisible, BorderLayout.CENTER);
        //filling employees table
        personalInfo = new JPanel(new GridBagLayout());
        personalInfo.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.BLACK), "Personal information"));
        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.BOTH;
        c.ipady = 200;
        c.gridx = 0;
        c.gridy = 0;
        c.weightx = 1;
        c.weighty = 0.5;
        employee.add(personalInfo, c);
        Dimension personalInfoDim = personalInfo.getMaximumSize();
        position = new JPanel(new GridBagLayout());
        position.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.BLACK), "Position"));
        c.fill = GridBagConstraints.BOTH;
        c.ipady = 100;
        c.gridx = 0;
        c.gridy = 1;
        c.weightx = 1;
        employee.add(position, c);
        photo = new JPanel();
        photo.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.BLACK), "Image"));
        c.fill = GridBagConstraints.BOTH;
        c.ipadx = 170;
        c.gridx = 1;
        c.gridy = 0;
        c.weightx = 1;
        c.gridheight = 2;
        employee.add(photo, c);
        address = new JPanel(new GridBagLayout());
        address.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.BLACK), "Address"));
        c.fill = GridBagConstraints.BOTH;
        c.ipady = 100;
        c.gridx = 0;
        c.gridy = 2;
        c.weightx = 1;
        c.gridwidth = 0;
        c.gridheight = 1;
        employee.add(address, c);
        //panels filling
        personalInfo.setMaximumSize(personalInfoDim);
        codeLabel = new JLabel("Code");
        code = new JTextField(10);
        personalInfo.add(codeLabel, makeGbc(0, 0, 20));
        personalInfo.add(code, makeGbc(1, 0, 100));
        nameLabel = new JLabel("Name");
        name = new JTextField(50);
        personalInfo.add(nameLabel, makeGbc(0, 1, 20));
        personalInfo.add(name, makeGbc(1, 1, 240));
        surnameLabel = new JLabel("Surname");
        surname = new JTextField(50);
        personalInfo.add(surnameLabel, makeGbc(0, 2, 20));
        personalInfo.add(surname, makeGbc(1, 2, 240));
        genderLabel = new JLabel("Gender");
        personalInfo.add(genderLabel, makeGbc(0, 3, 20));
        gender = new JComboBox(genderConstatns);
        personalInfo.add(gender, makeGbc(1, 3, 100));
        birthdayLabel = new JLabel("Birthday");
        personalInfo.add(birthdayLabel, makeGbc(0, 4, 20));
        birthday = new JTextField(20);
        birthday.setText("dd/mm/yyyy");
        birthday.addFocusListener(new FocusAdapter() {
            @Override
            public void focusGained(FocusEvent e) {
                birthday.setText("");
            }

            @Override
            public void focusLost(FocusEvent e) {
                SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
                Date date = null;
                try {
                    date = format.parse(birthday.getText());
                } catch (ParseException e1) {
                    e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                }
                float birthdayDate = date.getTime()/*Math.abs(1970 - Float.valueOf(birthday.getText().substring(birthday.getText().lastIndexOf('/') + 1)))*/;
                float today = System.currentTimeMillis();
                float ageFloat = (today - birthdayDate) / (31536000000f);
                age.setText(String.valueOf(Math.round(ageFloat) - 1));
            }
        });
        personalInfo.add(birthday, makeGbc(1, 4, 100));
        ageLabel = new JLabel("Age");
        personalInfo.add(ageLabel, makeGbc(0, 5, 20));
        age = new JTextPane();
        age.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        age.setBackground(Color.LIGHT_GRAY);
        age.setEditable(false);
        personalInfo.add(age, makeGbc(1, 5, 20));
        //----
        positionLabel = new JLabel("Position");
        position.add(positionLabel, makeGbc(0, 0, 10));
        positionText = new JTextField(250);
        position.add(positionText, makeGbc(1, 0, 250));
        salaryLabel = new JLabel("Salary");
        position.add(salaryLabel, makeGbc(0, 1, 10));
        Object[] b = {"BYR", "USD", "EUR"};
        salaryCurrency = new JComboBox(b);
        position.add(salaryCurrency, makeGbc(1, 1, 50));
        salary = new JTextField(100);
        position.add(salary, makeGbc(2, 1, 100));
        //----
        countryLabel = new JLabel("Country");
        address.add(countryLabel, makeGbc(0, 0, 10));
        country = new JComboBox(countries);
        address.add(country, makeGbc(1, 0, 75));
        cityLabel = new JLabel("City");
        address.add(cityLabel, makeGbc(0, 1, 10));
        city = new JTextField(50);
        address.add(city, makeGbc(1, 1, 100));
        locationLabel = new JLabel("Location");
        address.add(locationLabel, makeGbc(0, 2, 10));
        location = new JTextArea(3, 50);
        address.add(new JScrollPane(location), makeGbc(1, 2, 100));
        left.setEnabled(false);
        leftToBorder.setEnabled(false);
        rightToBorder.setEnabled(false);
        right.setEnabled(false);
        //data insertion
        if (msg.equals("edit")) {
            left.setEnabled(true);
            leftToBorder.setEnabled(true);
            rightToBorder.setEnabled(true);
            right.setEnabled(true);
            actionPerformed(new ActionEvent(leftToBorder, 1, "<<"));

        }
        //finnalization
        additionForm.setVisible(true);
        pack();
    }

    private GridBagConstraints makeGbc(int x, int y, int z) {
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridwidth = 1;
        gbc.gridheight = 1;
        gbc.gridx = x;
        gbc.gridy = y;
        gbc.ipadx = z;
        gbc.ipady = 0;
        gbc.weightx = 1;
        gbc.weighty = 0.01;
        gbc.anchor = GridBagConstraints.FIRST_LINE_START;
        gbc.insets = new Insets(0, 5, 0, 0);
        return gbc;
    }

    private Employees employeeAdd() {
        Map<String, Integer> currs = new HashMap<String, Integer>();
        Map<String, Integer> countries = new HashMap<String, Integer>();
        currs = DAOFactory.getInstance().getCurrencyDAO().getCurrencyMap();
        countries = DAOFactory.getInstance().getCountryDAO().getCountyriesMap();
        Currency curr = new Currency();
        Country countr = new Country();
        employeeObj = new Employees();
        employeeObj.setCode(Integer.valueOf(code.getText()));
        employeeObj.setName(name.getText());
        employeeObj.setSurname(surname.getText());
        employeeObj.setStringBirthday(birthday.getText());
        employeeObj.setGender(gender.getSelectedItem().toString().equals("Male") ? true : false);
        employeeObj.setPosition(positionText.getText());
        curr.setId(currs.get(salaryCurrency.getSelectedItem().toString().toUpperCase()));
        Set<String> currencySet = currs.keySet();
        for (String currency : currencySet) {
            if (currency.equals(salaryCurrency.getSelectedItem().toString())) {
                curr.setCurrency(salaryCurrency.getSelectedItem().toString());
            }
        }
        employeeObj.setSalaryCurrency(curr);
        employeeObj.setSalaryAmount(Double.valueOf(salary.getText()));
        employeeObj.setCity(city.getText());
        countr.setId(countries.get(country.getSelectedItem().toString().toUpperCase()));
        Set<String> countrySet = countries.keySet();
        for (String country1 : countrySet) {
            if (country1.equalsIgnoreCase(country.getSelectedItem().toString())) {
                countr.setName(country.getSelectedItem().toString().toUpperCase());
            }
        }
        employeeObj.setCountry(countr);
        employeeObj.setLocation(location.getText());
        return employeeObj;
    }

    private void employeeEdit() {
        employeesList.set(employeeIndex, employeeAdd());
//        List<Employees> tempList = new ArrayList<Employees>(employeesList);
        EmployeesTable.getInstance().setEmployeesList(employeesList);
    }

    public static AdditionForm getInstance(String msg) {
        if (instance != null) {
            instance.setVisible(true);
        }
        return instance = new AdditionForm(msg);
    }

    public boolean checker() {
        aboutInfo = new JDialog();
        aboutInfo.setTitle("Not all required fields are filled.");
        aboutInfo.setSize(560, 100);
        aboutInfo.setPreferredSize(new Dimension(560, 100));
        JLabel aboutLabel = new JLabel();
        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
        panel.setBorder(BorderFactory.createEmptyBorder(5, 25, 5, 25));
        panel.add(aboutLabel);
        aboutInfo.add(panel);
        String msg = new String("");
        if (code.getText().equals("")) {
            msg += "Code is empty ";
        }
        if (code.getText().length() > 20) {
            msg += "Code is to long ";
        }
        if (name.getText().equals("")) {
            msg += "Name is empty ";
        }
        if (name.getText().length() > 20) {
            msg += "Name is to long ";
        }
        if (surname.getText().equals("")) {
            msg += "Surname is empty ";
        }
        if (surname.getText().length() > 20) {
            msg += "Surname is to long ";
        }
        if (birthday.getText().equals("")) {
            msg += "Birthday is empty ";
        }
        if (salary.getText().equals("")) {
            msg += "Salary is empty ";
        }
        if (city.getText().length() > 50) {
            msg += "Length to long ";
        }
        if (msg.equals("")) {
            return true;
        } else {
            aboutLabel.setText(msg);
            aboutInfo.pack();
            aboutInfo.setVisible(true);
            return false;
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("Close")) {
            additionForm.setVisible(false);
            EmployeesTable.getInstance().getEmployeesTableForm().setVisible(true);
            instance = null;
        }
        if ((e.getActionCommand().equals("<")) && (employeeIndex != 0)) {
            employeeIndex--;
            rightToBorder.setEnabled(true);
        }
        if ((e.getActionCommand().equals("<<")) || (employeeIndex == 0)) {
            employeeIndex = 0;
            rightToBorder.setEnabled(true);
            leftToBorder.setEnabled(false);
        }
        if ((e.getActionCommand().equals(">>")) || (employeeIndex == employeesList.size() - 1)) {
            employeeIndex = employeesList.size() - 1;
            leftToBorder.setEnabled(true);
            rightToBorder.setEnabled(false);
        }
        if ((e.getActionCommand().equals(">")) && (employeeIndex != employeesList.size() - 1)) {
            employeeIndex++;
            leftToBorder.setEnabled(true);
        }
        if ((employeeIndex < employeesList.size()) && (employeeIndex >= 0)) {
            code.setText(String.valueOf(employeesList.get(employeeIndex).getCode()));
            name.setText(employeesList.get(employeeIndex).getName());
            surname.setText(employeesList.get(employeeIndex).getSurname());
            gender.setSelectedItem(employeesList.get(employeeIndex).getGender());
            birthday.setText(employeesList.get(employeeIndex).getStringBirthday());
            age.setText(String.valueOf(employeesList.get(employeeIndex).getAge()));
            positionText.setText(employeesList.get(employeeIndex).getPosition());
            salaryCurrency.setSelectedItem(employeesList.get(employeeIndex).getSalaryCurrency());
            salary.setText(String.valueOf(employeesList.get(employeeIndex).getSalaryAmount()));
            country.setSelectedItem(employeesList.get(employeeIndex).getCountry());
            city.setText(employeesList.get(employeeIndex).getCity());
            location.setText(employeesList.get(employeeIndex).getLocation());
        }
    }
}

